#include "caller.h"

#include <QDBusInterface>
#include <QDBusReply>
#include <QDebug>

const QString Caller::g_service = "io.github.add358.dbus.service";
const QString Caller::g_interface = "local.DBusServer.Person"; // 要定义成这个才能接收到nameChanged信号，有点奇怪

Caller::Caller(QObject *parent) : QObject(parent)
{
    // method 1
//    QDBusConnection::sessionBus().connect(g_service, "/", g_interface, "nameChanged", this, SLOT(onNameChanged(QString)));
    // method 2
    auto interface = new QDBusInterface(g_service, "/", g_interface,
                                        QDBusConnection::sessionBus(), this);
    connect(interface, SIGNAL(nameChanged(QString)),
            this, SLOT(onNameChanged(QString)));
}

void Caller::callByMsg()
{
    auto msg = QDBusMessage::createMethodCall(g_service, "/", g_interface, "setName");
    msg << QString("callByMsg");
    auto response = QDBusConnection::sessionBus().call(msg);
    qDebug() << response.type();

    msg = QDBusMessage::createMethodCall(g_service, "/", g_interface, "name");
    response = QDBusConnection::sessionBus().call(msg);
    if (response.type() == QDBusMessage::ReplyMessage) {
        auto args = response.arguments();
        qDebug() << __func__ << ": name=" << args.takeFirst().toString();
    }
}

void Caller::callByInterface()
{
    QDBusInterface interface(g_service, "/", g_interface);
    interface.call("setName", "callByInterface");

    QDBusReply<QString> reply = interface.call("name");
    if (reply.isValid()) {
        qDebug() << __func__ << "name=" << reply.value();
    } else {
        qDebug() << "[" << __func__ << "]: " << reply.error();
    }
}

void Caller::callAsync()
{
    QDBusInterface interface(g_service, "/", g_interface);
    interface.asyncCall("setName", "callAsync");

    auto async = interface.asyncCall("name");
    auto watcher = new QDBusPendingCallWatcher(async, this);
    connect(watcher, &QDBusPendingCallWatcher::finished,
            this, [](QDBusPendingCallWatcher *watcher){
        QDBusPendingReply<QString> reply = *watcher;
        if (reply.isValid()) {
            qDebug() << __func__ << " name=" << reply.value();
        } else {
            qDebug() << reply.error();
        }
    });
}

void Caller::onNameChanged(const QString &name)
{
    qDebug("%s(%s)[%d]", __FILE__, __func__, __LINE__);
    qDebug() << __func__ << ": name=" << name;
}
